package com.controller.lib.utils
import android.Manifest.permission
import android.content.Context
import android.content.pm.PackageManager
import android.content.pm.PackageManager.NameNotFoundException
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.text.TextUtils
import android.util.Log
import androidx.annotation.RequiresPermission
import androidx.core.app.ActivityCompat
import timber.log.Timber
import java.io.BufferedReader
import java.io.FileReader
import java.io.IOException
import java.net.Inet4Address
import java.net.Inet6Address
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.SocketException
import java.util.Collections
import java.util.Enumeration



/**
 * author : GeRui
 * date   : 2023/7/4 14:10
 * desc   :
 * version: 1.0
 */
object SystemUtils {
  const val TYPE_NO: Int = -1

  /**
   * 获取自己应用内部的版本号
   */
  fun getVersionCode(context: Context): Int {
    val manager = context.packageManager
    var code = 0
    try {
      val info = manager.getPackageInfo(context.packageName, 0)
      code = info.versionCode
    } catch (e: NameNotFoundException) {
      e.printStackTrace()
    }
    return code
  }

  /**
   * 获取自己应用内部的版本名
   */
  fun getVersionName(context: Context): String? {
    val manager = context.packageManager
    var name: String? = null
    try {
      val info = manager.getPackageInfo(context.packageName, 0)
      name = info.versionName
    } catch (e: NameNotFoundException) {
      e.printStackTrace()
    }
    return name
  }

  @RequiresPermission(permission.ACCESS_NETWORK_STATE)
  private fun getActiveNetworkInfo(context: Context): NetworkInfo? {
    val cm =
      context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        ?: return null
    return cm.activeNetworkInfo
  }

  /**
   * 获取当前的网络类型.
   *
   * @param context 上下文.
   * @return 当前的网络类型.
   */
  fun getNetType(context: Context): Int {
    val info = getActiveNetworkInfo(context)
    if (info != null) {
      return info.type
    }
    return TYPE_NO
  }

  /**
   * 是否为特定的Ip(神奇).
   * ps:192.168.5.1
   *
   * @return 是否为系统主动设置的IP.
   */
  private fun isMagicalIp(ip: String?): Boolean {
    Timber.i("isMagicalIp_%s", ip)
    return TextUtils.equals("192.168.5.1", ip)
  }

  fun isConnected(netType: Int): Boolean {
    Timber.i("isConnected_%s", netType)
    return netType == ConnectivityManager.TYPE_WIFI
        || netType == ConnectivityManager.TYPE_ETHERNET
  }

  /**
   * [ConnectivityManager.TYPE_ETHERNET].
   * [ConnectivityManager.TYPE_WIFI].
   *
   * @return 获取当前的网络类型(专用 ， 已过滤系统设置的有线ip).
   */
  fun getSpecialNetType(context: Context): Int {
    var type = getNetType(context)
    Timber.i("getSpecialNetType_%s", type)
    if (type == ConnectivityManager.TYPE_ETHERNET) {
      var ip: String? = null
      try {
        ip = hostIPAddress
        Timber.i("getSpecialNetType_%s", ip)
      } catch (e: Exception) {
        e.printStackTrace()
      }
      if (isMagicalIp(ip)) {
        type = TYPE_NO
        Timber.i("isMagicalIp")
      }
    }
    return type
  }

  val hostIPAddress: String?
    get() {
      var IPAddress: String? = null
      try {
        val nis: Enumeration<*> = NetworkInterface.getNetworkInterfaces()
        while (nis.hasMoreElements()) {
          val ni = nis.nextElement() as NetworkInterface
          val ias = ni.inetAddresses
          while (ias.hasMoreElements()) {
            val ia = ias.nextElement()
            if (ia is Inet6Address) {
              continue
            }
            val hostAddress = ia.hostAddress
            if ("127.0.0.1" != hostAddress) {
              IPAddress = hostAddress
              break
            }
          }
        }
      } catch (e: SocketException) {
        e.printStackTrace()
      }
      return IPAddress
    }

  val etherNetIP: String
    /**
     * 获取有线地址
     */
    get() {
      try {
        val en = NetworkInterface
          .getNetworkInterfaces()
        while (en.hasMoreElements()) {
          val intf = en.nextElement()
          val enumIpAddr = intf
            .inetAddresses
          while (enumIpAddr.hasMoreElements()) {
            val inetAddress = enumIpAddr.nextElement()
            if (!inetAddress.isLoopbackAddress
              && inetAddress is Inet4Address
            ) {
              return inetAddress.getHostAddress().toString()
            }
          }
        }
      } catch (ex: SocketException) {
        Timber.i("WifiPreference IpAddress:_%s", ex.toString())
      }
      return "0.0.0.0"
    }

  /**
   * 获取wifiIP地址
   */
  fun getWifiIP(context: Context): String? {
    val wifi = context
      .getSystemService(Context.WIFI_SERVICE) as WifiManager
    val wifiinfo = wifi.connectionInfo
    val intaddr = wifiinfo.ipAddress
    val byteaddr = byteArrayOf(
      (intaddr and 0xff).toByte(),
      (intaddr shr 8 and 0xff).toByte(), (intaddr shr 16 and 0xff).toByte(),
      (intaddr shr 24 and 0xff).toByte()
    )
    var addr: InetAddress? = null
    try {
      addr = InetAddress.getByAddress(byteaddr)
    } catch (e1: Exception) {
      e1.printStackTrace()
    }
    val mobileIp = addr!!.hostAddress
    return mobileIp
  }

  /**
   * 通过网络接口获取MAC地址
   * type = eth0,获取有线mac
   * type=wlan0,获取无线mac
   */
  fun getMac(type: String?): String? {
    try {
      val all: List<NetworkInterface> = Collections.list(NetworkInterface.getNetworkInterfaces())
      for (nif in all) {
        Timber.d("nif==%s", nif.name)
        if (!nif.name.equals(type, ignoreCase = true)) {
          continue
        }
        val macBytes = nif.hardwareAddress ?: return null

        val res1 = StringBuilder()
        for (b in macBytes) {
          res1.append(String.format("%02X:", b))
        }

        if (res1.length > 0) {
          res1.deleteCharAt(res1.length - 1)
        }
        Timber.d("MAC==%s", res1.toString())
        return res1.toString()
      }
    } catch (e: Exception) {
      e.printStackTrace()
    }
    return null
  }

  /**
   * 获取有线MAC
   * */
  fun getEthMac(): String {
    var macAddress = ""
    var br: BufferedReader? = null
    try {
      br = BufferedReader(FileReader("/sys/class/net/eth0/address"))
      macAddress = br.readLine().uppercase()
      Log.d("gerui", "macAddress: $macAddress")
    } catch (e: IOException) {
      e.printStackTrace()
    } finally {
      if (br != null) {
        try {
          br.close()
        } catch (e: IOException) {
          e.printStackTrace()
          Log.d("gerui", "IOException: ${e.message}")
        }
      }
    }
    return macAddress
  }

  /**
   * 获取无线MAC
   * */
  fun getWlanMac(): String {
    var macAddress = ""
    var br: BufferedReader? = null
    try {
      br = BufferedReader(FileReader("/sys/class/net/wlan0/address"))
      macAddress = br.readLine().uppercase()
      Log.d("gerui", "macAddress: $macAddress")
    } catch (e: IOException) {
      e.printStackTrace()
    } finally {
      if (br != null) {
        try {
          br.close()
        } catch (e: IOException) {
          e.printStackTrace()
          Log.d("gerui", "IOException: ${e.message}")
        }
      }
    }
    return macAddress
  }

  /**
   * 获取设备序列号
   * */
  fun getSerialNumber(context: Context?): String? {
    if (ActivityCompat.checkSelfPermission(
        context!!,
        permission.READ_PHONE_STATE
      ) != PackageManager.PERMISSION_GRANTED
    ) {
      return null
    }

    var serial: String? = null
    serial = if (VERSION.SDK_INT >= VERSION_CODES.O) {
      Build.getSerial()
    } else {
      Build.SERIAL
    }
    return serial
  }

  // 获取设备型号
  fun getDeviceModel(): String {
    return Build.MODEL
  }

  // 获取厂商自定义的 Build Number（如三星的 BUILD_NUMBER）
  fun getDisplayId(): String {
    return try {
      "Android " + VERSION.RELEASE
    } catch (e: java.lang.Exception) {
      Timber.e("getDisplayId: %s", e.message)
      "Unknown"
    }

  }
}
